package com.gxd.fastdfs.web;

import com.gxd.commons.model.Result;
import com.gxd.commons.utils.FtpUtils;
import com.gxd.commons.utils.SFTPUtils;
import com.gxd.commons.utils.StringUtils;
import com.gxd.fastdfs.config.SFTPConfigProperties;
import com.gxd.fastdfs.csource.CFastDFSClient;
import com.gxd.fastdfs.csource.FastDFSException;
import com.gxd.fastdfs.csource.FastDfsFile;
import com.jcraft.jsch.JSchException;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:gxd
 * @Description:
 * @Date: 11:14 2018/1/13
 * @Modified By:
 */
@SuppressWarnings("SpringJavaAutowiringInspection") //加这个注解让IDE 不报: Could not autowire
@Controller
@RequestMapping("/file2")
public class CSourceUploadController {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired(required = false)
    private SFTPConfigProperties sftpConfigProperties;
    
    @Value("${fastdfs.webServerUrl:http://192.168.50.34:8088/dfs/}")
    private String webServerUrl;

    @RequestMapping(value = "/toupload", method = RequestMethod.GET)
    private String toUpload(){
        return "view/upload";
    }

    /**
     * 访问路径为：http://ip:port/file/fileupload
     * @return
     */
    @RequestMapping(value = "/fileupload1", method = RequestMethod.GET)
    public String upload() {
        return "view/fileupload1";
    }

    @RequestMapping(value = "/fileupload2", method = RequestMethod.GET)
    public String upload2() {
        return "view/fileupload2";
    }

    @RequestMapping(value = "/fileThumb", method = RequestMethod.GET)
    public String fileThumb() {
        return "view/fileThumb";
    }

    /**
     * 访问路径为：http://ip:port/file/mutifileupload
     * @return
     */
    @RequestMapping(value = "/filebatchupload", method = RequestMethod.GET)
    public String batchUpload() {
        return "view/filebatchupload";
    }

    /**
     * 读取ftp路径并上传fastdfs
     * @return
     */
    @RequestMapping(value = "/ftpfileupload", method = RequestMethod.GET)
    private String ftpToUpload(){
        return "view/ftpfileupload";
    }

    /**
     * 读取sftp路径并上传fastdfs
     * @return
     */
    @RequestMapping(value = "/sftpfileupload", method = RequestMethod.GET)
    private String sftpToUpload(){
        return "view/sftpfileupload";
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public   Map<String,String> fileUp(MultipartHttpServletRequest multipartFile, HttpServletRequest request){
        logger.debug("upload开始上传...");
        long start = System.currentTimeMillis();
        Map<String,String> result = new HashMap<String,String>(16);
        //参数名称
        String param = request.getParameter("param");
        if(StringUtils.isEmpty(param)){
            result.put("result","false");
            result.put("msg","请添加参数");
        }
        InputStream inputStream  = null;
        String path = "";
        String fileName = "";
        try {
            MultipartFile file = multipartFile.getFile(param);
            fileName = file.getOriginalFilename();
            String[] fileAbsolutePath={};
            byte[] fileBuff = null;
            inputStream = file.getInputStream();
            if(inputStream!=null){
                int len1 = inputStream.available();
                fileBuff = new byte[len1];
                inputStream.read(fileBuff);
            }
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
            FastDfsFile fastDFSFile = new FastDfsFile(fileName, fileBuff, ext);
            CFastDFSClient cFastDFSClient = new CFastDFSClient();
            fileAbsolutePath = cFastDFSClient.uploadByByte(fastDFSFile);  //upload to fastdfs
            path = webServerUrl+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
            logger.debug("upload上传成功，路径："+path);
            result.put("result","true");
            //图片地址
            result.put("srckey",path);
            long end = System.currentTimeMillis();
            logger.debug("upload总体耗时:" + StringUtils.formatDuring(end - start)+"millis:"+(end - start));
        }catch (IOException e){
            result.put("result","false");
            logger.error("file:"+fileName,e.fillInStackTrace());
        } catch (FastDFSException e) {
            result.put("result","false");
            logger.error("file:"+fileName,e.fillInStackTrace());
        } finally {
            if (inputStream !=null){
                try {
                    inputStream.close();
                }catch (IOException io){
                    logger.error(io.getMessage());
                }
            }
        }
        return result;
    }



    @RequestMapping(value = "/upload1", method = RequestMethod.POST)
    @ResponseBody
    public  String upload(@RequestParam("file") MultipartFile file) {
        logger.debug("upload1开始上传...");
        long start = System.currentTimeMillis();
        String path = "";
        InputStream inputStream = null;
        if (!file.isEmpty()) {
            try {
                String[] fileAbsolutePath={};
                String fileName = file.getOriginalFilename();
                logger.debug("fileName:"+fileName);
                //获取文件的扩展名
                String extension = FilenameUtils.getExtension(fileName);
                if(StringUtils.isEmpty(extension)){
                    extension ="jpg";
                }
                byte[] fileBuff = null;
                inputStream =file.getInputStream();
                if(inputStream!=null){
                    int len1 = inputStream.available();
                    fileBuff = new byte[len1];
                    inputStream.read(fileBuff);
                }
                FastDfsFile fastDFSFile = new FastDfsFile(fileName, fileBuff, extension);
                CFastDFSClient cFastDFSClient = new CFastDFSClient();
                fileAbsolutePath = cFastDFSClient.uploadByByte(fastDFSFile);  //upload to fastdfs
                path = webServerUrl+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
                logger.debug("upload1上传成功,路径:"+path);
                long end = System.currentTimeMillis();
                logger.debug("upload1总体耗时:" + StringUtils.formatDuring(end - start)+"millis:"+(end - start));
            } catch (FileNotFoundException e) {
                logger.error("上传失败："+e.getMessage());
                return "上传失败," + e.getMessage();
            } catch (IOException e) {
                logger.error("上传失败："+e.getMessage());
                return "上传失败," + e.getMessage();
            } catch (FastDFSException e) {
                logger.error("上传失败："+e.getMessage());
                return "上传失败," + e.getMessage();
            }finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return "上传成功,路径:"+path;
        } else {
            return "上传失败，因为文件是空的.";
        }
    }


    /**
     * 多文件上传 主要是使用了MultipartHttpServletRequest和MultipartFile
     *
     * @param request
     * @return
     * @author gx
     * @create 2018年1月17日
     */
    @RequestMapping(value = "/upload/batch", method = RequestMethod.POST)
    public   @ResponseBody String batchUpload(HttpServletRequest request) {
        logger.debug("upload/batch 开始上传...");
        long start = System.currentTimeMillis();
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        MultipartFile file = null;
        String fileName = "";
        String[] fileAbsolutePath={};
        StringBuffer sb = new StringBuffer();
        String path = "";
        InputStream inputStream = null;
        try {
            for (int i = 0; i < files.size(); ++i) {
                file = files.get(i);
                if (!file.isEmpty()) {
                    fileName = file.getOriginalFilename();
                    byte[] fileBuff = null;
                    inputStream = file.getInputStream();
                    if(inputStream!=null){
                        int len1 = inputStream.available();
                        fileBuff = new byte[len1];
                        inputStream.read(fileBuff);
                    }
                    String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
                    FastDfsFile fastDFSFile = new FastDfsFile(fileName, fileBuff, ext);
                    CFastDFSClient cFastDFSClient = new CFastDFSClient();
                    fileAbsolutePath = cFastDFSClient.uploadByByte(fastDFSFile);
                    path = webServerUrl+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
                    sb.append("文件："+fileName+"，上传路径："+path+"<br/>");
                } else {
                    return "You failed to upload " + i + " because the file was empty.";
                }
            }
        } catch (Exception e) {
            return "You failed to upload  => " + e.getMessage();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        // 总体耗时
        logger.debug("cost time:" + StringUtils.formatDuring(end - start));
        return "upload successful<br/>"+sb.toString();
    }


    /**
     * 读取网络图片，通过流上传
     * @param path
     * @return
     */
    @RequestMapping(value = "/upload2")
    @ResponseBody
    public  Result uploadFile(String path) {
        logger.debug("upload2 开始上传...");
        long start = System.currentTimeMillis();
        String filePath = "";
        Result result = new Result();
        InputStream inputStream = null;
        ByteArrayOutputStream bos = null;
        String[] fileAbsolutePath = {};
        if (StringUtils.isBlank(path)) {
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("文件路径为空");
            return result;
        }
        try {
            //new一个URL对象
            URL url = new URL(path);
            //打开链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            ////设置请求方式为"GET"
            //conn.setRequestMethod("GET");
            ////超时响应时间为30秒
            conn.setConnectTimeout(30 * 1000);
            conn.setRequestProperty("Accept-Encoding", "identity");
            //通过输入流获取图片数据
            conn.connect();
            inputStream = conn.getInputStream();
            bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while((len= inputStream.read(buffer))!=-1){
                bos.write(buffer,0,len);
            }
            byte[] dataImage = bos.toByteArray();
            bos.close();
            inputStream.close();
            //bos.flush();
            String extension = FilenameUtils.getExtension(path);
            if(StringUtils.isEmpty(extension)){
                extension ="jpg";
            }
            // 读取流
            //byte[] fileBuffs = new byte[inputStream.available()];
            //inputStream.read(fileBuffs, 0, fileBuffs.length);
            FastDfsFile fastDFSFile = new FastDfsFile(path, dataImage, extension);
            CFastDFSClient cFastDFSClient = new CFastDFSClient();
            fileAbsolutePath = cFastDFSClient.uploadByByte(fastDFSFile);  //upload to fastdfs
            filePath = webServerUrl+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
            logger.debug("upload2上传成功，路径："+filePath);
            long end = System.currentTimeMillis();
            logger.debug("upload2总体耗时:" + StringUtils.formatDuring(end - start)+"millis:"+(end - start));

        } catch (IOException e) {
            logger.error(e.toString());
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("上传出现异常：" + e.getMessage());
            return result;
        } catch (FastDFSException e) {
            logger.error(e.toString());
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("上传出现异常：" + e.getMessage());
            return result;
        }
        result.addAttribute("filePath", filePath);
        result.setState(0);
        result.setSuccess(true);
        result.setMessage("上传成功");
        return result;
    }

    @RequestMapping(value = "/ftp/upload")
    @ResponseBody
    public   Result ftpUploadFile(String path) {
        logger.debug("/ftp/upload开始上传...");
        long start = System.currentTimeMillis();
        String filePath = "";
        FTPClient ftpClient = null;
        Result result = new Result();
        InputStream inputStream = null;
        if (StringUtils.isBlank(path)) {
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("文件路径为空");
            return result;
        }
        try {
            logger.debug("图片路径 : " + path);
            //通过输入流获取图片数据
            long startTime = System.currentTimeMillis();
            ftpClient = FtpUtils.getFtpClient(path);
            String remoteFileName = "";
            remoteFileName = path.substring(path.lastIndexOf("/") + 1);
            logger.debug("图片名称：" + remoteFileName);
            inputStream = ftpClient.retrieveFileStream(FtpUtils.encodingPath(remoteFileName));
            logger.debug("获取图片数据 SPEND TIME : " + StringUtils.formatDuring(System.currentTimeMillis() - startTime));
            String[] fileAbsolutePath={};
            String fileName = remoteFileName;
            byte[] fileBuff = null;
            if(inputStream!=null){
                int len1 = inputStream.available();
                fileBuff = new byte[len1];
                inputStream.read(fileBuff);
            }
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
            FastDfsFile fastDFSFile = new FastDfsFile(fileName, fileBuff, ext);
            CFastDFSClient cFastDFSClient = new CFastDFSClient();
            fileAbsolutePath = cFastDFSClient.uploadByByte(fastDFSFile);  //upload to fastdfs
            filePath = webServerUrl+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
            logger.debug("/ftp/upload上传成功,路径："+filePath);
            long end = System.currentTimeMillis();
            logger.debug("/ftp/upload总体耗时: " + StringUtils.formatDuring(end - start));
        } catch (Exception e) {
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("上传出现异常：" + e.getMessage());
            return result;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                    logger.debug("inputStream.close()关闭成功");
                    ftpClient.completePendingCommand();
                    logger.debug("ftpClient.completePendingCommand()关闭成功");
                } else {
                    result.setState(-1);
                    result.setSuccess(false);
                    result.setMessage("上传出现异常：服务器无资源或者图片路径不对或者无权限");
                    return result;
                }
            } catch (IOException e) {
                result.setState(-1);
                result.setSuccess(false);
                result.setMessage("上传出现异常：" + e.getMessage());
                return result;
            }
            FtpUtils.releaseFtpClient(ftpClient);
            logger.debug("releaseFtpClient关闭成功");
        }
        result.addAttribute("filePath", filePath);
        result.setState(0);
        result.setSuccess(true);
        result.setMessage("上传成功");
        return result;
    }

    @RequestMapping(value = "/sftp/upload")
    @ResponseBody
    public   Result sftpUploadFile(String path) {
        logger.debug("/sftp/upload开始上传...");
        long start = System.currentTimeMillis();
        String filePath = "";
        Result result = new Result();
        InputStream inputStream = null;
        if (StringUtils.isBlank(path)) {
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("文件路径为空");
            return result;
        }
        try {
            //通过输入流获取图片数据
            String host = sftpConfigProperties.getHost();
            int port = sftpConfigProperties.getPort();
            String usename = sftpConfigProperties.getUsername();
            String password = sftpConfigProperties.getPassword();
            SFTPUtils.connectServer(host,port,usename,password);
            inputStream = SFTPUtils.readFile(path);

            String[] fileAbsolutePath={};
            String fileName = path.substring(path.lastIndexOf("/")+1);
            byte[] fileBuff = null;
            if(inputStream!=null){
                int len1 = inputStream.available();
                fileBuff = new byte[len1];
                inputStream.read(fileBuff);
            }
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
            FastDfsFile fastDFSFile = new FastDfsFile(fileName, fileBuff, ext);
            CFastDFSClient cFastDFSClient = new CFastDFSClient();
            fileAbsolutePath = cFastDFSClient.uploadByByte(fastDFSFile);  //upload to fastdfs
            filePath = webServerUrl+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
            logger.debug("/sftp/upload上传成功,路径："+filePath);
            long end = System.currentTimeMillis();
            logger.debug("/sftp/upload总体耗时: " + StringUtils.formatDuring(end - start));
        } catch (IOException e) {
            logger.error("上传出现异常：" +e.toString());
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("上传出现异常：" + e.getMessage());
            return result;
        }  catch (JSchException e) {
            logger.error("上传出现异常：" +e.toString());
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("上传出现异常：" + e.getMessage());
            return result;
        } catch (FastDFSException e) {
            logger.error("上传出现异常：" +e.toString());
            result.setState(-1);
            result.setSuccess(false);
            result.setMessage("上传出现异常：" + e.getMessage());
            return result;
        } finally {
            try {
                if(inputStream !=null){
                    inputStream.close();
                }
            } catch (IOException e) {
                logger.error("上传出现异常：" +e.toString());
                result.setState(-1);
                result.setSuccess(false);
                result.setMessage("上传出现异常：" + e.getMessage());
                return result;
            }
        }
        result.addAttribute("filePath", filePath);
        result.setState(0);
        result.setSuccess(true);
        result.setMessage("上传成功");
        return result;
    }
}
